package cn.wolf.lbs;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import cn.wolf.tools.Log;

/**
 * <h3>GPS定位监听器    </h3>
 * <p>监听GPS位置变化，并从中获取最精确的位置，并广播出去。</p>
 */
public class MyLocationListener implements LocationListener {
	private Location currentLocation;
	private static final int CHECK_INTERVAL = 1000 * 30;
	private LocationManager mLocationManager;
	private Context mContext;
	private ILbsCallBack iCall;

	/**
	 * 定位监听器
	 * @param context
	 * 		上下文
	 * @param locationManager
	 * 		定位管理器
	 */
	public MyLocationListener(Context context, LocationManager locationManager) {
		this.mLocationManager = locationManager;
		this.mContext = context;
	}

	/**
	 * 定位监听器，可以回调
	 * @param context
	 * 		上下文
	 * @param locationManager
	 * 		定位管理器
	 * @param iCall
	 * 		回调接口
	 */
	public MyLocationListener(Context context, LocationManager locationManager, ILbsCallBack iCall) {
		this(context, locationManager);
		this.iCall = iCall;
	}

	@Override
	public void onLocationChanged(Location location) {
		Log.d("Got New Location of provider:" + location.getProvider());

		if (currentLocation != null) {
			if (isBetterLocation(location, currentLocation)) {
				Log.d("It's a better location");
				currentLocation = location;
			} else {
				Log.d("location is not very good!");

				if (iCall == null) {
					// 广播定位信息
					LocationUtils.sendBroadcast(currentLocation, mContext,
							LocationUtils.LOCATION_ACTION);
				} else {
					// 回调外部接口
					iCall.call(location);
				}

				// 移除GPS定位监听器
				mLocationManager.removeUpdates(this);
			}
		} else {
			Log.d("It's first location");
			currentLocation = location;
		}

		// 移除基于LocationManager.NETWORK_PROVIDER的监听器
		if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) {
			mLocationManager.removeUpdates(this);
		}
	}

	@Override
	public void onProviderDisabled(String provider) {
	}

	@Override
	public void onProviderEnabled(String provider) {
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
	}

	private boolean isBetterLocation(Location location, Location currentBestLocation) {
		if (currentBestLocation == null) {
			// A new location is always better than no location
			return true;
		}

		// Check whether the new location fix is newer or older
		long timeDelta = location.getTime() - currentBestLocation.getTime();
		boolean isSignificantlyNewer = timeDelta > CHECK_INTERVAL;
		boolean isSignificantlyOlder = timeDelta < -CHECK_INTERVAL;
		boolean isNewer = timeDelta > 0;

		// If it's been more than two minutes since the current location,
		// use the new location
		// because the user has likely moved
		if (isSignificantlyNewer) {
			return true;
			// If the new location is more than two minutes older, it must
			// be worse
		} else if (isSignificantlyOlder) {
			return false;
		}

		// Check whether the new location fix is more or less accurate
		int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
		boolean isLessAccurate = accuracyDelta > 0;
		boolean isMoreAccurate = accuracyDelta < 0;
		boolean isSignificantlyLessAccurate = accuracyDelta > 200;

		// Check if the old and new location are from the same provider
		boolean isFromSameProvider = isSameProvider(location.getProvider(),
				currentBestLocation.getProvider());

		// Determine location quality using a combination of timeliness and
		// accuracy
		if (isMoreAccurate) {
			return true;
		} else if (isNewer && !isLessAccurate) {
			return true;
		} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
			return true;
		}
		return false;
	}

	/** Checks whether two providers are the same */
	private boolean isSameProvider(String provider1, String provider2) {
		if (provider1 == null) {
			return provider2 == null;
		}
		return provider1.equals(provider2);
	}
}
